#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>

void pr_mask(const char *str)
{
    sigset_t sigset;
    int errno_save;

    errno_save = errno; /* we can be called by signal handlers */
    if (sigprocmask(0, NULL, &sigset) < 0)
    {
        perror("sigpromask error");
        exit(0);
    }

    printf("%s", str);

    if (sigismember(&sigset, SIGINT)) printf("SIGINT ");
    if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");

    printf("\n");
    errno = errno_save;
}

static void sig_int(int sig)
{
    pr_mask("In sig_int: ");
    return;
}

int main(int argc, char const* argv[])
{
    sigset_t newmask, oldmask, zeromask;

    if (signal(SIGINT, sig_int) == SIG_ERR)
    {
        perror("signal error");
        exit(0);
    }

    sigemptyset(&zeromask);
    sigemptyset(&newmask);
    sigaddset(&newmask, SIGINT);
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
    {
        perror("sigprocmask error");
        exit(0);
    }

    /* critical region of code */
    pr_mask("in critical region:");

    /* allow all signals and pause */
    if (sigsuspend(&zeromask) != -1)
    {
        perror("sigsuspend error");
        exit(0);
    }

    pr_mask("after return from suspend: ");

    /* reset signal mask which unblocks SIGINT */
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
    {
        perror("SIG_SETMASK error");
        exit(0);
    }
    
    pr_mask("after unblock SIGINT: ");

    /* and continue processing... */

    return 0;
}
